﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using SnmpSharpNet;

namespace Network_Toolbox.src
{
    class Equipement
    {
        private String nom;
        private String ip;
        private String user;
        private String mdp;
        private String mdp_enable;
        private String communaute;
        private String type_connexion;
        private String serial_number ;
        private String description ;
        private Port[] tab_ports_voisins;
        private int nb_voisin;

        public Equipement(String nom, String ip, String user, String mdp, String mdp_enable, String communaute, String type_connexion, String serial_number, String description, Port[] tab_ports_voisins, int nb_voisin)
        {
            this.nom = nom;
            this.ip = ip;
            this.user = user;
            this.mdp = mdp;
            this.mdp_enable = mdp_enable;
            this.communaute = communaute;
            this.type_connexion = type_connexion;
            this.serial_number = serial_number;
            this.description = description;
            this.tab_ports_voisins = tab_ports_voisins;
            this.nb_voisin = nb_voisin;
        }

        public Equipement(String ip, String user, String mdp, String mdp_enable, String communaute, String type_connexion)
        {
            this.nom = null;
            this.ip = ip;
            this.user = user;
            this.mdp = mdp;
            this.mdp_enable = mdp_enable;
            this.communaute = communaute;
            this.type_connexion = type_connexion;
            this.serial_number = null;
            this.description = null;
            this.tab_ports_voisins = new Port[200];
            this.nb_voisin = 0;

        }

        public Equipement(String nom)
        {
            this.nom = nom;
            this.ip = null;
            this.user = null;
            this.mdp = null;
            this.mdp_enable = null;
            this.communaute = null;
            this.type_connexion = null;
            this.serial_number = null;
            this.description = null;
            this.tab_ports_voisins = new Port[200];
            this.nb_voisin = 0;

        }

        public Equipement(String ip, String communaute)
        {
            this.nom = null;
            this.ip = ip;
            this.user = null;
            this.mdp = null;
            this.mdp_enable = null;
            this.communaute = communaute;
            this.type_connexion = null;
            this.serial_number = null;
            this.description = null;
            this.tab_ports_voisins = new Port[200];
            this.nb_voisin = 0;

        }

        public String getNom()
        {
            return this.nom;
        }
        public void setNom(String newNom)
        {
            this.nom = newNom;
        }

        public String getIp()
        {
            return this.ip;
        }
        public void setIp(String newIp)
        {
            this.ip = newIp;
        }

        public String getUser()
        {
            return this.user;
        }

        public void setUser(String newUser)
        {
            this.user = newUser;
        }

        public String getMdp()
        {
            return this.mdp;
        }
        public void setMdp(String newMdp)
        {
            this.mdp = newMdp;
        }

        public String getMdp_enable()
        {
            return this.mdp_enable;
        }
        public void setMdp_enable(String newMdp_enable)
        {
            this.mdp_enable = newMdp_enable;
        }

        public String getCommunaute()
        {
            return this.communaute;
        }
        public void setCommunaute(String newCommunaute)
        {
            this.communaute = newCommunaute;
        }

        public String getType_connexion()
        {
            return this.type_connexion;
        }
        public void setType_connexion(String newType_connexion)
        {
            if (newType_connexion.Equals("ssh") || newType_connexion.Equals("telnet"))
            {
                this.type_connexion = newType_connexion;
            }
            else
            {
                throw new ExceptionType_connexionInvalide("les types de connexion doivent être soit ssh, soit telnet");
            }

        }

        public String getSerial_number()
        {
            return this.serial_number;
        }
        public void setSerial_number(String newSerial_number)
        {
            this.serial_number = newSerial_number;
        }

        public String getDescription()
        {
            return this.description;
        }
        public void setDescription(String newDesc)
        {
            this.description = newDesc;
        }

        public int getNbVoisin()
        {
            return this.nb_voisin;
        }

        public void ajoutPort(Port p)
        {
            this.tab_ports_voisins.SetValue(p,this.nb_voisin);
            this.nb_voisin++;
        }

        public void ajoutPort(String nom, String equipVoisin)
        {
            this.tab_ports_voisins[nb_voisin] = new Port(nom, equipVoisin);
            this.nb_voisin++;
        }
        
        public String ToString()
        {
            String liste_cdp = "";

            for (int i = 0; i < this.nb_voisin; i++)
            {
                liste_cdp = liste_cdp + this.tab_ports_voisins[i].ToString() + "\n";
            }
            return ("nom : " + this.getNom() + "\nip : " + this.getIp() + "\ndescription : " + this.getDescription()+ "\nCDP :\n"+liste_cdp);
        }

        // Comparaison du nom uniquement
        public bool Equals(Equipement e)
        {
            return (this.getNom().Equals(e.getNom()));
        }


        public Port[] getTab_ports_voisins()
        {
            return (this.tab_ports_voisins);
        }

        public Port this[int index]
        {
            get
            {
                return tab_ports_voisins[index];
            }
        }


        public void discoverSNMP()
        {
            SimpleSnmp snmp = new SimpleSnmp(this.getIp(),161,this.getCommunaute(),1000,0);
            Dictionary<Oid, AsnType> result_hostname;
            Dictionary<Oid, AsnType> result_serial;
            Dictionary<Oid, AsnType> result_description;
            // Règle (expression régulière) pour le découpage de la description
            Regex maRegleSuppr = new Regex(@"\n|\r");
            Regex maRegleSplit = new Regex(@", ");

            // Règle (expression régulière) pour le découpage du nom du voisin
            Regex maRegleSup = new Regex(@"\..*$");

            Dictionary<Oid, AsnType> result_neighbors_equip;
            Dictionary<Oid, AsnType> result_neighbors_port;

            String[,] tab_equip = new String[200,2] ;
            int compteur_cdp = 0;

            snmp.Timeout =2000;
            result_serial = snmp.Walk(SnmpVersion.Ver2, "1.3.6.1.4.1.9.3.6.3");
            result_description = snmp.Walk(SnmpVersion.Ver2, "1.3.6.1.2.1.1.1");
            result_hostname = snmp.Walk(SnmpVersion.Ver2, "1.3.6.1.4.1.9.2.1.3");
            result_neighbors_equip = snmp.Walk(SnmpVersion.Ver2, "1.3.6.1.4.1.9.9.23.1.2.1.1.6");
            result_neighbors_port = snmp.Walk(SnmpVersion.Ver2, "1.3.6.1.4.1.9.9.23.1.2.1.1.7");
            
            try
            {
                foreach (KeyValuePair<Oid, AsnType> kvp in result_hostname)
                {
                    this.nom = kvp.Value.ToString();
                }
                foreach (KeyValuePair<Oid, AsnType> kvp in result_serial)
                {
                    this.serial_number = kvp.Value.ToString();
                }

                foreach (KeyValuePair<Oid, AsnType> kvp in result_description)
                {
                    Regex maRegleNet = new Regex(@"\s");

                    this.description = maRegleNet.Replace(kvp.Value.ToString(), " ");
                }


                foreach (KeyValuePair<Oid, AsnType> kvp in result_neighbors_port)
                {
                    tab_equip[compteur_cdp, 0] = kvp.Value.ToString();
                    compteur_cdp++;
                }
                // Remise à zéro du compteur pour 
                compteur_cdp = 0;
                foreach (KeyValuePair<Oid, AsnType> kvp in result_neighbors_equip)
                {
                    String temp = maRegleSup.Replace(kvp.Value.ToString(), "");
                    tab_equip[compteur_cdp, 1] = temp;
                    compteur_cdp++;
                }

           }
           catch (Exception e)
            {
                throw new Exception(e.Message);
                //throw new Exception("ip : " + this.getIp() + " n'est pas joignable");
            }
            // Vider le tableau pour eviter d'avoir des erreurs lors d'une nouvelle découverte SNMP
            for (int x = 0; x < this.nb_voisin; x++)
            {
                this.tab_ports_voisins.SetValue(null, x);
            }
            this.nb_voisin = 0;


            for (int i = 0; i < compteur_cdp; i++)
            {
                this.ajoutPort(tab_equip[i, 0], tab_equip[i, 1]);
            }

            
   
        }
    }
}
